home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / pascal / tpxms.com / TPXMS.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1989-10-06  |  23.4 KB  |  724 lines

  1. (****************************************************************************
  2.  
  3.           TPXMS.PAS  v1.01   Written by Vernon E. Davis   10/06/89
  4.  
  5.           for use with HIMEM.SYS, an Extended Memory Device Driver
  6.  
  7.  
  8.  NOTE: The current version of HIMEM.SYS ( v2.06 ), as of this release, does
  9.        not support the following Function Calls:
  10.  
  11.                  $0F : Reallocate Extended Memory Block
  12.                  $10 : Request Upper Memory Block
  13.                  $11 : Release Upper Memory Block
  14.  
  15.        This source code is written with these functions available, so when
  16.        HIMEM.SYS does support them, no recompilation will be necessary.
  17.  
  18.  Revision History:
  19.  
  20.    Date    Rev.  Description
  21.  --------  ----  -----------------------------------------------------------
  22.  07/30/89  1.00  Initial Release
  23.  10/06/89  1.01  Fix error in MoveExtMemBlockXMS ( need Segment Override ).
  24.                  Add Procedure PokeAddrXMS for Conventional Memory Moves.
  25.  
  26.  ****************************************************************************)
  27.  
  28. Unit TPXMS;
  29. Interface
  30. Uses
  31.    DOS;
  32. Type
  33.    Bit32Struct = LongInt;
  34.  
  35.    ExtMemMoveStruct =
  36.    Record
  37.       Length       : Bit32Struct;
  38.       SourceHandle : Word;
  39.       SourceOffset : Bit32Struct;
  40.       DestHandle   : Word;
  41.       DestOffset   : Bit32Struct
  42.    End;
  43.  
  44.    EMBHandleStruct =
  45.    Record
  46.       LockCount   : Byte;
  47.       FreeHandles : Byte;
  48.       BlockLenKB  : Word
  49.    End;
  50.  
  51.    UMBSegmentStruct =
  52.    Record
  53.       Segment   : Word;
  54.       UMBSizeKB : Word
  55.    End;
  56.  
  57. Var
  58.    isXMS       : Boolean;
  59.    XMSResult   : Word;
  60.    XMSError    : Byte;
  61.    XMM_Control : Array[0..1] of Word;
  62.  
  63. (* Procedure/Function Declarations *)
  64.  
  65.    Function  XMSErrorMsg : String;
  66.    Procedure PokeAddrXMS(Var b32 : Bit32Struct; sb,ob : Word);
  67.    Function  EXISTXMS : Boolean;
  68.    Procedure GetVerHiMem;
  69.    Procedure GetRevHiMem;
  70.    Procedure GetMemHMA(malloc : Word);
  71.    Procedure FreeMemHMA;
  72.    Procedure GlobalEnableA20;
  73.    Procedure GlobalDisableA20;
  74.    Procedure LocalEnableA20;
  75.    Procedure LocalDisableA20;
  76.    Procedure QueryA20;
  77.    Procedure QueryFreeMemXMS;
  78.    Procedure QueryFreeBlockXMS;
  79.    Function  AllocExtMemBlockXMS(malloc : Word) : Word;
  80.    Procedure FreeExtMemBlockXMS(handle : Word);
  81.    Procedure MoveExtMemBlockXMS(Var MoveStructure : ExtMemMoveStruct);
  82.    Function  LockExtMemBlockXMS(handle : Word) : Bit32Struct;
  83.    Procedure UnlockExtMemBlockXMS(handle : Word);
  84.    Procedure EMBHandleInfoXMS(handle : Word; Var HStructure : EMBHandleStruct);
  85.    Procedure ReallocExtMemBlockXMS(handle,KBsize : Word);
  86.    Procedure ReqUpperMemBlockUMB(malloc : Word; Var USeg : UMBSegmentStruct);
  87.    Procedure RelUpperMemBlockUMB(segment : Word);
  88.  
  89. Implementation
  90.  
  91. Function XMSErrorMsg : String;
  92. Var
  93.    XMSMsg : String;
  94. Begin
  95.    XMSMsg := '';
  96.    Case XMSError of
  97.    $00 : XMSMsg := '';
  98.    $80 : XMSMsg := '80 : XMS Function not implemented';
  99.    $81 : XMSMsg := '81 : VDISK detected';
  100.    $82 : XMSMsg := '82 : A20 Error';
  101.    $8E : XMSMsg := '8E : General Driver Error';
  102.    $8F : XMSMsg := '8F : Unrecoverable Driver Error';
  103.    $90 : XMSMsg := '90 : HMA does not exist';
  104.    $91 : XMSMsg := '91 : HMA in use by another process';
  105.    $92 : XMSMsg := '92 : Memory requested less than /HMAMIN= parameter';
  106.    $93 : XMSMsg := '93 : HMA not allocated';
  107.    $94 : XMSMsg := '94 : A20 is enabled';
  108.    $A0 : XMSMsg := 'A0 : All of Extended Memory is allocated';
  109.    $A1 : XMSMsg := 'A1 : No Extended Memory Handles available';
  110.    $A2 : XMSMsg := 'A2 : Extended Memory Handle is invalid';
  111.    $A3 : XMSMsg := 'A3 : Extended Move Structure: Source Handle is invalid';
  112.    $A4 : XMSMsg := 'A4 : Extended Move Structure: Source Offset is invalid';
  113.    $A5 : XMSMsg := 'A5 : Extended Move Structure: Destination Handle is invalid';
  114.    $A6 : XMSMsg := 'A6 : Extended Move Structure: Destination Offset is invalid';
  115.    $A7 : XMSMsg := 'A7 : Extended Move Structure: Length is invalid';
  116.    $A8 : XMSMsg := 'A8 : Extended Move Structure: Move has invalid overlap';
  117.    $A9 : XMSMsg := 'A9 : Parity Error';
  118.    $AA : XMSMsg := 'AA : Block is not locked';
  119.    $AB : XMSMsg := 'AB : Block is locked';
  120.    $AC : XMSMsg := 'AC : Block Lock Count has overflowed';
  121.    $AD : XMSMsg := 'AD : Block Lock has failed';
  122.    $B0 : XMSMsg := 'B0 : A smaller Upper Memory Block is available';
  123.    $B1 : XMSMsg := 'B1 : No Upper Memory Blocks are available';
  124.    $B2 : XMSMsg := 'B2 : Upper Memory Block Segment Number is invalid'
  125.    Else
  126.       XMSMsg := 'Unknown Error has occured'
  127.    End;
  128.    If XMSMsg <> '' Then
  129.       XMSErrorMsg := 'XMS Error $' + XMSMsg
  130. End;
  131.  
  132. Procedure PokeAddrXMS(Var b32 : Bit32Struct; sb,ob : Word);
  133.  
  134.    Procedure PTR_W_W(iptr : Pointer; incr,wval : Word);
  135.    Var
  136.       vptr    : ^Word;
  137.    Begin
  138.       vptr    := Ptr(Seg(iptr^),Ofs(iptr^)+incr);
  139.       vptr^   := wval
  140.    End;
  141.  
  142. Begin
  143.    PTR_W_W(Addr(b32),0,ob);
  144.    PTR_W_W(Addr(b32),2,sb)
  145. End;
  146.  
  147. Function EXISTXMS : Boolean;
  148. Var
  149.    regs : Registers;
  150. Begin
  151.    regs.AX := $4300;
  152.    Intr($2F,regs);
  153.    If regs.al = $80 Then
  154.    Begin
  155.       regs.AX := $4310;
  156.       Intr($2F,regs);
  157.       XMM_Control[0] := regs.bx;
  158.       XMM_Control[1] := regs.es;
  159.       EXISTXMS := TRUE
  160.    End
  161.    Else
  162.       EXISTXMS := FALSE
  163. End;
  164.  
  165. Procedure GetVerHiMem;
  166. (* XMSResult = Version level in BCD *)
  167. Var
  168.    ax : Word;
  169. Begin
  170.    XMSResult := 1;
  171.    XMSError  := 0;
  172.    If NOT isXMS Then
  173.    Begin
  174.       XMSResult := 0;
  175.       XMSError  := $80;
  176.       Exit
  177.    End;
  178.    Inline
  179.    (  $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  180.       $B8/$00/$00/                         {  MOV  AX,0000               }
  181.       $55/                                 {  PUSH BP                    }
  182.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  183.       $5D/                                 {  POP  BP                    }
  184.       $89/$86/ax                           {  MOV  ax[BP],AX             }
  185.    );
  186.    XMSResult := ax
  187. End;
  188.  
  189. Procedure GetRevHiMem;
  190. (* XMSResult = Internal Revision level in BCD *)
  191. Var
  192.    bx : Word;
  193. Begin
  194.    XMSResult := 1;
  195.    XMSError  := 0;
  196.    If NOT isXMS Then
  197.    Begin
  198.       XMSResult := 0;
  199.       XMSError  := $80;
  200.       Exit
  201.    End;
  202.    Inline
  203.    (  $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  204.       $B8/$00/$00/                         {  MOV  AX,0000               }
  205.       $55/                                 {  PUSH BP                    }
  206.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  207.       $5D/                                 {  POP  BP                    }
  208.       $89/$9E/bx                           {  MOV  bx[BP],BX             }
  209.    );
  210.    XMSResult := bx
  211. End;
  212.  
  213. Procedure GetMemHMA(malloc : Word);
  214. Var
  215.    ax : Word;
  216.    bl : Byte;
  217. Begin
  218.    XMSResult := 1;
  219.    XMSError  := 0;
  220.    If NOT isXMS Then
  221.    Begin
  222.       XMSResult := 0;
  223.       XMSError  := $80;
  224.       Exit
  225.    End;
  226.    Inline
  227.    (  $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  228.       $8B/$96/malloc/                      {  MOV  DX,malloc[BP]         }
  229.       $B8/$00/$01/                         {  MOV  AX,0100               }
  230.       $55/                                 {  PUSH BP                    }
  231.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  232.       $5D/                                 {  POP  BP                    }
  233.       $89/$86/ax/                          {  MOV  ax[BP],AX             }
  234.       $88/$9E/bl                           {  MOV  bl[BP],BL             }
  235.    );
  236.    XMSResult := ax;
  237.    XMSError  := bl
  238. End;
  239.  
  240. Procedure FreeMemHMA;
  241. Var
  242.    ax : Word;
  243.    bl : Byte;
  244. Begin
  245.    XMSResult := 1;
  246.    XMSError  := 0;
  247.    If NOT isXMS Then
  248.    Begin
  249.       XMSResult := 0;
  250.       XMSError  := $80;
  251.       Exit
  252.    End;
  253.    Inline
  254.    (  $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  255.       $B8/$00/$02/                         {  MOV  AX,0200               }
  256.       $55/                                 {  PUSH BP                    }
  257.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  258.       $5D/                                 {  POP  BP                    }
  259.       $89/$86/ax/                          {  MOV  ax[BP],AX             }
  260.       $88/$9E/bl                           {  MOV  bl[BP],BL             }
  261.    );
  262.    XMSResult := ax;
  263.    XMSError  := bl
  264. End;
  265.  
  266. Procedure GlobalEnableA20;
  267. Var
  268.    ax : Word;
  269.    bl : Byte;
  270. Begin
  271.    XMSResult := 1;
  272.    XMSError  := 0;
  273.    If NOT isXMS Then
  274.    Begin
  275.       XMSResult := 0;
  276.       XMSError  := $80;
  277.       Exit
  278.    End;
  279.    Inline
  280.    (  $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  281.       $B8/$00/$03/                         {  MOV  AX,0300               }
  282.       $55/                                 {  PUSH BP                    }
  283.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  284.       $5D/                                 {  POP  BP                    }
  285.       $89/$86/ax/                          {  MOV  ax[BP],AX             }
  286.       $88/$9E/bl                           {  MOV  bl[BP],BL             }
  287.    );
  288.    XMSResult := ax;
  289.    XMSError  := bl
  290. End;
  291.  
  292. Procedure GlobalDisableA20;
  293. Var
  294.    ax : Word;
  295.    bl : Byte;
  296. Begin
  297.    XMSResult := 1;
  298.    XMSError  := 0;
  299.    If NOT isXMS Then
  300.    Begin
  301.       XMSResult := 0;
  302.       XMSError  := $80;
  303.       Exit
  304.    End;
  305.    Inline
  306.    (  $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  307.       $B8/$00/$04/                         {  MOV  AX,0400               }
  308.       $55/                                 {  PUSH BP                    }
  309.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  310.       $5D/                                 {  POP  BP                    }
  311.       $89/$86/ax/                          {  MOV  ax[BP],AX             }
  312.       $88/$9E/bl                           {  MOV  bl[BP],BL             }
  313.    );
  314.    XMSResult := ax;
  315.    XMSError  := bl
  316. End;
  317.  
  318. Procedure LocalEnableA20;
  319. Var
  320.    ax : Word;
  321.    bl : Byte;
  322. Begin
  323.    XMSResult := 1;
  324.    XMSError  := 0;
  325.    If NOT isXMS Then
  326.    Begin
  327.       XMSResult := 0;
  328.       XMSError  := $80;
  329.       Exit
  330.    End;
  331.    Inline
  332.    (  $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  333.       $B8/$00/$05/                         {  MOV  AX,0500               }
  334.       $55/                                 {  PUSH BP                    }
  335.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  336.       $5D/                                 {  POP  BP                    }
  337.       $89/$86/ax/                          {  MOV  ax[BP],AX             }
  338.       $88/$9E/bl                           {  MOV  bl[BP],BL             }
  339.    );
  340.    XMSResult := ax;
  341.    XMSError  := bl
  342. End;
  343.  
  344. Procedure LocalDisableA20;
  345. Var
  346.    ax : Word;
  347.    bl : Byte;
  348. Begin
  349.    XMSResult := 1;
  350.    XMSError  := 0;
  351.    If NOT isXMS Then
  352.    Begin
  353.       XMSResult := 0;
  354.       XMSError  := $80;
  355.       Exit
  356.    End;
  357.    Inline
  358.    (  $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  359.       $B8/$00/$06/                         {  MOV  AX,0600               }
  360.       $55/                                 {  PUSH BP                    }
  361.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  362.       $5D/                                 {  POP  BP                    }
  363.       $89/$86/ax/                          {  MOV  ax[BP],AX             }
  364.       $88/$9E/bl                           {  MOV  bl[BP],BL             }
  365.    );
  366.    XMSResult := ax;
  367.    XMSError  := bl
  368. End;
  369.  
  370. Procedure QueryA20;
  371. (* XMSResult = 1 if A20 is physically enabled, else 0 *)
  372. Var
  373.    ax : Word;
  374. Begin
  375.    XMSResult := 1;
  376.    XMSError  := 0;
  377.    If NOT isXMS Then
  378.    Begin
  379.       XMSResult := 0;
  380.       XMSError  := $80;
  381.       Exit
  382.    End;
  383.    Inline
  384.    (  $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  385.       $B8/$00/$07/                         {  MOV  AX,0700               }
  386.       $55/                                 {  PUSH BP                    }
  387.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  388.       $5D/                                 {  POP  BP                    }
  389.       $89/$86/ax                           {  MOV  ax[BP],AX             }
  390.    );
  391.    XMSResult := ax
  392. End;
  393.  
  394. Procedure QueryFreeMemXMS;
  395. (* XMSResult = total free Extended Memory in kilobytes *)
  396. Var
  397.    ax : Word;
  398. Begin
  399.    XMSResult := 1;
  400.    XMSError  := 0;
  401.    If NOT isXMS Then
  402.    Begin
  403.       XMSResult := 0;
  404.       XMSError  := $80;
  405.       Exit
  406.    End;
  407.    Inline
  408.    (  $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  409.       $B8/$00/$08/                         {  MOV  AX,0800               }
  410.       $55/                                 {  PUSH BP                    }
  411.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  412.       $5D/                                 {  POP  BP                    }
  413.       $89/$86/ax                           {  MOV  ax[BP],AX             }
  414.    );
  415.    XMSResult := ax
  416. End;
  417.  
  418. Procedure QueryFreeBlockXMS;
  419. (* XMSResult = largest free block of Extended Memory in kilobytes *)
  420. Var
  421.    dx : Word;
  422. Begin
  423.    XMSResult := 1;
  424.    XMSError  := 0;
  425.    If NOT isXMS Then
  426.    Begin
  427.       XMSResult := 0;
  428.       XMSError  := $80;
  429.       Exit
  430.    End;
  431.    Inline
  432.    (  $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  433.       $B8/$00/$08/                         {  MOV  AX,0800               }
  434.       $55/                                 {  PUSH BP                    }
  435.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  436.       $5D/                                 {  POP  BP                    }
  437.       $89/$96/dx                           {  MOV  dx[BP],DX             }
  438.    );
  439.    XMSResult := dx
  440. End;
  441.  
  442. Function AllocExtMemBlockXMS(malloc : Word) : Word;
  443. (* If successful, returns handle to Extended Memory Block *)
  444. Var
  445.    ax : Word;
  446.    dx : Word;
  447.    bl : Byte;
  448. Begin
  449.    XMSResult := 1;
  450.    XMSError  := 0;
  451.    If NOT isXMS Then
  452.    Begin
  453.       XMSResult := 0;
  454.       XMSError  := $80;
  455.       AllocExtMemBlockXMS := 0;
  456.       Exit
  457.    End;
  458.    Inline
  459.    (  $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  460.       $8B/$96/malloc/                      {  MOV  DX,malloc[BP]         }
  461.       $B8/$00/$09/                         {  MOV  AX,0900               }
  462.       $55/                                 {  PUSH BP                    }
  463.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  464.       $5D/                                 {  POP  BP                    }
  465.       $89/$86/ax/                          {  MOV  ax[BP],AX             }
  466.       $88/$9E/bl/                          {  MOV  bl[BP],BL             }
  467.       $89/$96/dx                           {  MOV  dx[BP],DX             }
  468.    );
  469.    XMSResult := ax;
  470.    XMSError  := bl;
  471.    AllocExtMemBlockXMS := dx
  472. End;
  473.  
  474. Procedure FreeExtMemBlockXMS(handle : Word);
  475. Var
  476.    ax : Word;
  477.    bl : Byte;
  478. Begin
  479.    XMSResult := 1;
  480.    XMSError  := 0;
  481.    If NOT isXMS Then
  482.    Begin
  483.       XMSResult := 0;
  484.       XMSError  := $80;
  485.       Exit
  486.    End;
  487.    Inline
  488.    (  $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  489.       $8B/$96/handle/                      {  MOV  DX,handle[BP]         }
  490.       $B8/$00/$0A/                         {  MOV  AX,0A00               }
  491.       $55/                                 {  PUSH BP                    }
  492.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  493.       $5D/                                 {  POP  BP                    }
  494.       $89/$86/ax/                          {  MOV  ax[BP],AX             }
  495.       $88/$9E/bl                           {  MOV  bl[BP],BL             }
  496.    );
  497.    XMSResult := ax;
  498.    XMSError  := bl
  499. End;
  500.  
  501. Procedure MoveExtMemBlockXMS(Var MoveStructure : ExtMemMoveStruct);
  502. (* NOTE: This procedure assumes that the ExtMemMove structure is valid *)
  503. (* Changed 10/06/89: Needed to force ES: override for XMM Call         *)
  504. Var
  505.    ax,
  506.    segs,
  507.    ofss : Word;
  508.    bl   : Byte;
  509. Begin
  510.    XMSResult := 1;
  511.    XMSError  := 0;
  512.    If NOT isXMS Then
  513.    Begin
  514.       XMSResult := 0;
  515.       XMSError  := $80;
  516.       Exit
  517.    End;
  518.    segs := Seg(MoveStructure);
  519.    ofss := Ofs(MoveStructure);
  520.    Inline
  521.    (  $1E/                                 {  PUSH DS                    }
  522.       $1E/                                 {  PUSH DS                    }
  523.       $07/                                 {  POP  ES                    }
  524.       $8B/$86/segs/                        {  MOV  AX,segs[BP]           }
  525.       $8E/$D8/                             {  MOV  DS,AX                 }
  526.       $8B/$B6/ofss/                        {  MOV  SI,ofss[BP]           }
  527.       $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  528.       $B8/$00/$0B/                         {  MOV  AX,0B00               }
  529.       $55/                                 {  PUSH BP                    }
  530.       $26/                                 {  ES:                        }
  531.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  532.       $5D/                                 {  POP  BP                    }
  533.       $1F/                                 {  POP  DS                    }
  534.       $89/$86/ax/                          {  MOV  ax[BP],AX             }
  535.       $88/$9E/bl                           {  MOV  bl[BP],BL             }
  536.    );
  537.    XMSResult := ax;
  538.    XMSError  := bl
  539. End;
  540.  
  541. Function LockExtMemBlockXMS(handle : Word) : Bit32Struct;
  542. Var
  543.    ax,bx,dx : Word;
  544. Begin
  545.    XMSResult := 1;
  546.    XMSError  := 0;
  547.    If NOT isXMS Then
  548.    Begin
  549.       XMSResult := 0;
  550.       XMSError  := $80;
  551.       LockExtMemBlockXMS := 0;
  552.       Exit
  553.    End;
  554.    Inline
  555.    (  $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  556.       $8B/$96/handle/                      {  MOV  DX,handle[BP]         }
  557.       $B8/$00/$0C/                         {  MOV  AX,0C00               }
  558.       $55/                                 {  PUSH BP                    }
  559.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  560.       $5D/                                 {  POP  BP                    }
  561.       $89/$86/ax/                          {  MOV  ax[BP],AX             }
  562.       $89/$9E/bx/                          {  MOV  bx[BP],BX             }
  563.       $89/$96/dx                           {  MOV  dx[BP],DX             }
  564.    );
  565.    XMSResult := ax;
  566.    LockExtMemBlockXMS := (dx SHL 8) + bx
  567. End;
  568.  
  569. Procedure UnlockExtMemBlockXMS(handle : Word);
  570. Var
  571.    ax : Word;
  572.    bl : Byte;
  573. Begin
  574.    XMSResult := 1;
  575.    XMSError  := 0;
  576.    If NOT isXMS Then
  577.    Begin
  578.       XMSResult := 0;
  579.       XMSError  := $80;
  580.       Exit
  581.    End;
  582.    Inline
  583.    (  $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  584.       $8B/$96/handle/                      {  MOV  DX,handle[BP]         }
  585.       $B8/$00/$0D/                         {  MOV  AX,0D00               }
  586.       $55/                                 {  PUSH BP                    }
  587.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  588.       $5D/                                 {  POP  BP                    }
  589.       $89/$86/ax/                          {  MOV  ax[BP],AX             }
  590.       $88/$9E/bl                           {  MOV  bl[BP],BL             }
  591.    );
  592.    XMSResult := ax;
  593.    XMSError  := bl
  594. End;
  595.  
  596. Procedure EMBHandleInfoXMS(handle : Word; Var HStructure : EMBHandleStruct);
  597. Var
  598.    ax,bx,dx : Word;
  599. Begin
  600.    XMSResult := 1;
  601.    XMSError  := 0;
  602.    If NOT isXMS Then
  603.    Begin
  604.       XMSResult := 0;
  605.       XMSError  := $80;
  606.       Exit
  607.    End;
  608.    Inline
  609.    (  $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  610.       $8B/$96/handle/                      {  MOV  DX,handle[BP]         }
  611.       $B8/$00/$0E/                         {  MOV  AX,0E00               }
  612.       $55/                                 {  PUSH BP                    }
  613.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  614.       $5D/                                 {  POP  BP                    }
  615.       $89/$86/ax/                          {  MOV  ax[BP],AX             }
  616.       $89/$9E/bx/                          {  MOV  bx[BP],BX             }
  617.       $89/$96/dx                           {  MOV  dx[BP],DX             }
  618.    );
  619.    XMSResult := ax;
  620.    With HStructure Do
  621.    Begin
  622.       LockCount   := Hi(bx);
  623.       FreeHandles := Lo(bx);
  624.       BlockLenKB  := dx
  625.    End
  626. End;
  627.  
  628. Procedure ReallocExtMemBlockXMS(handle,KBsize : Word);
  629. Var
  630.    ax : Word;
  631.    bl : Byte;
  632. Begin
  633.    XMSResult := 1;
  634.    XMSError  := 0;
  635.    If NOT isXMS Then
  636.    Begin
  637.       XMSResult := 0;
  638.       XMSError  := $80;
  639.       Exit
  640.    End;
  641.    Inline
  642.    (  $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  643.       $8B/$96/handle/                      {  MOV  DX,handle[BP]         }
  644.       $8B/$9E/KBSize/                      {  MOV  BX,KBSize[BP]         }
  645.       $B8/$00/$0F/                         {  MOV  AX,0F00               }
  646.       $55/                                 {  PUSH BP                    }
  647.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  648.       $5D/                                 {  POP  BP                    }
  649.       $89/$86/ax/                          {  MOV  ax[BP],AX             }
  650.       $88/$9E/bl                           {  MOV  bl[BP],BL             }
  651.    );
  652.    XMSResult := ax;
  653.    XMSError  := bl
  654. End;
  655.  
  656. Procedure ReqUpperMemBlockUMB(malloc : Word; Var USeg : UMBSegmentStruct);
  657. Var
  658.    ax,bx,dx : Word;
  659. Begin
  660.    XMSResult := 1;
  661.    XMSError  := 0;
  662.    If NOT isXMS Then
  663.    Begin
  664.       XMSResult := 0;
  665.       XMSError  := $80;
  666.       Exit
  667.    End;
  668.    Inline
  669.    (  $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  670.       $8B/$96/malloc/                      {  MOV  DX,malloc[BP]         }
  671.       $B8/$00/$10/                         {  MOV  AX,1000               }
  672.       $55/                                 {  PUSH BP                    }
  673.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  674.       $5D/                                 {  POP  BP                    }
  675.       $89/$86/ax/                          {  MOV  ax[BP],AX             }
  676.       $89/$9E/bx/                          {  MOV  bx[BP],BX             }
  677.       $89/$96/dx                           {  MOV  dx[BP],DX             }
  678.    );
  679.    XMSResult := ax;
  680.    With USeg Do
  681.    Begin
  682.       Segment := bx;
  683.       If XMSResult = 1 Then
  684.          UMBSizeKB := malloc
  685.       Else
  686.          UMBSizeKB := dx
  687.    End
  688. End;
  689.  
  690. Procedure RelUpperMemBlockUMB(segment : Word);
  691. Var
  692.    ax : Word;
  693.    bl : Byte;
  694. Begin
  695.    XMSResult := 1;
  696.    XMSError  := 0;
  697.    If NOT isXMS Then
  698.    Begin
  699.       XMSResult := 0;
  700.       XMSError  := $80;
  701.       Exit
  702.    End;
  703.    Inline
  704.    (  $BF/XMM_Control/                     {  MOV  DI,XMM_Control        }
  705.       $8B/$96/segment/                     {  MOV  DX,segment[BP]        }
  706.       $B8/$00/$11/                         {  MOV  AX,1100               }
  707.       $55/                                 {  PUSH BP                    }
  708.       $FF/$1D/                             {  CALL FAR[DI] (XMM_Control) }
  709.       $5D/                                 {  POP  BP                    }
  710.       $89/$86/ax/                          {  MOV  ax[BP],AX             }
  711.       $88/$9E/bl                           {  MOV  bl[BP],BL             }
  712.    );
  713.    XMSResult := ax;
  714.    XMSError  := bl
  715. End;
  716.  
  717. Begin
  718.    XMM_Control[0] := 0;
  719.    XMM_Control[1] := 0;
  720.    XMSResult      := 1;
  721.    XMSError       := 0;
  722.    isXMS          := EXISTXMS;
  723. End.
  724.